package org.zh.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.Charset;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import java.util.Timer;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CommonStatic {


    public static final String http_ContentType = "Content-Type";
    public static final String http_Accept = "Accept";
    public static final String http_AcceptCharset = "Accept-Charset";
    public static final String http_json = "application/json";

    public static final String rcRegistry = "/rc/zhOpen/registry";
    public static final String rcHeartBeat = "/rc/zhOpen/heartBeat";

    public static final Random random = new Random();
    public static final Timer timer = new Timer();
    public static final ObjectMapper om = new ObjectMapper();
    public static final ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
    public static final HttpClient httpClient_1_1 = HttpClient.newBuilder().executor(executorService).version(HttpClient.Version.HTTP_1_1).followRedirects(HttpClient.Redirect.NEVER).connectTimeout(Duration.ofSeconds(5)).build();

    static {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        om.registerModule(new JavaTimeModule().addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)));
    }
    public static HttpRequest.BodyPublisher getJSONRequestBody(Object body) throws JsonProcessingException {
       return HttpRequest.BodyPublishers.ofString(om.writeValueAsString(body));
    }

    public static HttpResponse.BodyHandler<String> getJSONResponseBody() throws JsonProcessingException {
        return HttpResponse.BodyHandlers.ofString();
    }
    public static <T> HttpResponse<T> smartHttpPUT(URI uri,HttpRequest.BodyPublisher bodyPublisher, HttpResponse.BodyHandler<T> bodyHandler){
        try {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(uri)
                    .PUT(bodyPublisher)
                    .header(http_ContentType, http_json)
                    .header(http_Accept, http_json)
                    .header(http_AcceptCharset, Charset.defaultCharset().name()).build();
            return httpClient_1_1.send(request, bodyHandler);
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static CompletableFuture<HttpResponse<String>>  smartHttpPUTJSON(String uri, String body) {
        try {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(uri))
                    .PUT(HttpRequest.BodyPublishers.ofString(om.writeValueAsString(body)))
                    .header(http_ContentType, http_json)
                    .header(http_Accept, http_json)
                    .header(http_AcceptCharset, Charset.defaultCharset().name()).build();
            return httpClient_1_1.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> HttpResponse<T> smartHttpPOST(URI uri, HttpRequest.BodyPublisher bodyPublisher, HttpResponse.BodyHandler<T> bodyHandler) {
        try {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(uri)
                    .POST(bodyPublisher)
                    .header(http_ContentType, http_json)
                    .header(http_Accept, http_json)
                    .header(http_AcceptCharset, Charset.defaultCharset().name()).build();
            return httpClient_1_1.send(request, bodyHandler);
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static CompletableFuture<HttpResponse<String>> smartHttpPOSTJSON(String uri, Object  body) {
        try {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(uri))
                    .POST(HttpRequest.BodyPublishers.ofString(om.writeValueAsString(body)))
                    .version(HttpClient.Version.HTTP_1_1)
                    .header(http_ContentType, http_json)
                    .header(http_Accept, http_json)
                    .header(http_AcceptCharset, Charset.defaultCharset().name()).build();
            return httpClient_1_1.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


}
